package cz.cuni.mff.ufal.volk.services;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import cz.cuni.mff.ufal.volk.Speech;
import cz.cuni.mff.ufal.volk.Text;

/**
 * Common wrapper on several text to speech systems.
 *
 * @author Bartłomiej Etenkowski
 */
public class TextToSpeechSet implements TextToSpeech {

  //[start] logger
  @SuppressWarnings("unused")
  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger
      .getLogger(TextToSpeechSet.class);
  //[end]

  private final Object sync = new Object(); // synchronization object

  private final Set<TextToSpeech> underlying = new LinkedHashSet<TextToSpeech>();

  public boolean addUnderlyingService(TextToSpeech tts) {
    tts.getClass();
    synchronized (sync) {
      return underlying.add(tts);
    }
  }

  public boolean removeUnderlyingService(TextToSpeech tts) {
    tts.getClass();
    synchronized (sync) {
      return underlying.remove(tts);
    }
  }

  @Override
  public boolean languageSupported(String language) {
    language.getClass();
    synchronized (sync) {
      for (TextToSpeech tts : underlying) {
        if (tts.languageSupported(language)) {
          return true;
        }
      }
    }
    return false;
  }

  @Override
  public List<String> supportedLanguages() {
    List<String> supported = new ArrayList<String>(underlying.size());
    Set<String> alreadyAdded = new HashSet<String>(underlying.size());
    synchronized (sync) {
      for (TextToSpeech tts : underlying) {
        for (String language : tts.supportedLanguages()) {
          if (!alreadyAdded.contains(language)) {
            supported.add(language);
            alreadyAdded.add(language);
          }
        }
      }
    }
    return supported;
  }

  @Override
  public Speech process(Text text, String voice) {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public List<String> availableVoices(String language) {
    // TODO Auto-generated method stub
    return null;
  }
}
